package com.oauth.yahoo.server.controller;

import java.io.IOException;
import java.util.Enumeration;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.scribe.custom.bean.Contact;
import org.scribe.http.Request;
import org.scribe.http.Response;
import org.scribe.http.Request.Verb;
import org.scribe.oauth.Scribe;
import org.scribe.oauth.Token;
import org.springframework.beans.factory.annotation.Required;

import com.oauth.common.server.OAuthGwtController;
import com.oauth.common.server.beans.OAuthAccessToken;
import com.oauth.common.server.beans.OAuthRequestToken;
import com.oauth.common.server.util.OAuthRequestUtil;
import com.oauth.components.client.beans.OAuthUrl;
import com.oauth.logging.OAuthLogger;
import com.oauth.service.generic.beans.OAuthServiceBean;
import com.oauth.yahoo.client.beans.Mail;
import com.oauth.yahoo.client.beans.YahooModel;
import com.oauth.yahoo.client.beans.YahooOAuthVerifier;
import com.oauth.yahoo.client.exception.YahooOAuthException;
import com.oauth.yahoo.client.rpc.YahooRemoteService;
import com.oauth.yahoo.server.beans.YahooRequestToken;
import com.oauth.yahoo.server.constants.YahooConstants;
import com.oauth.yahoo.server.service.YahooOAuthService;

public class YahooGwtController extends OAuthGwtController implements YahooRemoteService {

	private static final long serialVersionUID = -5758464341967618224L;

	private YahooOAuthService mYahooOAuthService;

	private OAuthLogger logger = OAuthLogger.getLogger(this.getClass());
	
	private static final String YAHOO_ACCESS_TOKEN = "yahooAccessToken";
	private static final String YAHOO_REQUEST_TOKEN = "yahooRequestToken";
	private static final ResourceBundle applicationProps = ResourceBundle
			.getBundle("yahooFriends", Locale.getDefault());
	private static final Properties props = convertResourceBundleToProperties(applicationProps);
	/**
	 * Convert ResourceBundle into a Properties object.
	 * 
	 * @param resource
	 *            a resource bundle to convert.
	 * @return Properties a properties version of the resource bundle.
	 */
	private static Properties convertResourceBundleToProperties(
			ResourceBundle resource) {
		Properties properties = new Properties();

		Enumeration<String> keys = resource.getKeys();
		while (keys.hasMoreElements()) {
			String key = keys.nextElement();
			properties.put(key, resource.getString(key));
		}

		return properties;
	}
	@Override
	public OAuthUrl getSignInUrl() throws YahooOAuthException {
		
//		HttpServletRequest request = getThreadLocalRequest();
//		String tokenString = (String)request.getAttribute(YAHOO_REQUEST_TOKEN);
//		
//		OAuthUrl authUrl = new OAuthUrl();
//		authUrl.setOAuthUrl("https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token="
//								+ tokenString);
//		return authUrl;
		
		
		YahooRequestToken requestToken;
		try {
			requestToken = mYahooOAuthService.getRequestToken();
		} catch (Exception e) {
			logger.error("Error in getting request token", e);
			throw new com.oauth.yahoo.client.exception.YahooOAuthException();
		}
		OAuthRequestUtil.createTokenCookies(getHttpResponse(), requestToken,
				YahooConstants.YAHOO_TOKEN_COOKIE, YahooConstants.YAHOO_TOKEN_SECRETCOOKIE);
		OAuthUrl oauthUrl = new OAuthUrl();
		oauthUrl.setOAuthUrl(requestToken.getAuthorizationUrl());
		System.out.println("Returning authorization url as:"+oauthUrl);
		return oauthUrl;

		/*
	
		String oauthVerifier = request.getParameter("oauthVerifier");
		//HttpSession httpSession = request.getSession();
		HttpServletResponse response = getThreadLocalResponse();
		Scribe scribe = new Scribe(props);
		if (oauthVerifier == null) {
			Token requestToken = scribe.getRequestToken();
			//httpSession.setAttribute(YAHOO_REQUEST_TOKEN, requestToken);
			String tokenString = requestToken.getToken();
			try {
				response
						.sendRedirect("https://api.login.yahoo.com/oauth/v2/request_auth?oauth_token="
								+ tokenString);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		} else {
			Token requestToken = (Token) httpSession
					.getAttribute(YAHOO_REQUEST_TOKEN);
			
			Token accessToken = null;
			if(requestToken != null) {
				accessToken = scribe.getAccessToken(requestToken,
					oauthVerifier);
				httpSession.setAttribute(YAHOO_REQUEST_TOKEN, null);
				httpSession.setAttribute(YAHOO_ACCESS_TOKEN, accessToken);
			} else {
				accessToken = (Token) httpSession
					.getAttribute(YAHOO_ACCESS_TOKEN);
			}
			if(accessToken == null) {
				throw new RuntimeException("Error while trying to get yahoo access token. accessToken=null");
			}
			Request oauthGuidRequest = new Request(Verb.GET,
					"http://social.yahooapis.com/v1/me/guid");
			scribe.signRequest(oauthGuidRequest, accessToken);
			Response guidResponse = oauthGuidRequest.send();
			String guidResp = guidResponse.getBody();

			String guid = "";//getGuid(guidResp);
			Request oauthRequest = new Request(Verb.GET,
					"http://social.yahooapis.com/v1/user/" + guid
							+ "/contacts?format=json&count=500&out=name,email");
			scribe.signRequest(oauthRequest, accessToken);
			Response oauthResponse = oauthRequest.send();
			String responseBody = oauthResponse.getBody();
			if(oauthResponse.getCode()!=200){
				logger.error(responseBody);
				throw new RuntimeException("Error while trying to fetch contacts from yahoo. Response Code="+oauthResponse.getCode());
			}
			System.out.println(oauthResponse.getCode());
			System.out.println(responseBody);
			//List<Contact> contactsList = yahooContactsParser.parseJson(responseBody);
			
			
//			ContactFormatterUtil.processContactsList(request, contactsList);
//			
//			DynaValidatorForm df = (DynaValidatorForm) form;
//			ContactFormBean[] contactArray = new ContactFormBean[contactsList.size()];
//			int i =0;
//			for (Contact contact : contactsList) {
//				contactArray[i] = new ContactFormBean();
//				contactArray[i].setEmail(contact.getEmail());
//				contactArray[i].setFirstName(contact.getFirstName());
//				contactArray[i].setLastName(contact.getLastName());
//				contactArray[i].setSelected(false);
//				i++;
//			}
//			ContactFormatterUtil.addPhotoAndScreenName(contactArray);
//			df.set("contacts", contactArray);
//			request.setAttribute("inviteContactsForm", df);
			
			
		}
	
		YahooRequestToken requestToken;
		try {
			requestToken = mYahooOAuthService.getRequestToken();
		} catch (Exception e) {
			logger.error("Error in getting request token", e);
			throw new com.oauth.yahoo.client.exception.YahooOAuthException();
		}
		OAuthRequestUtil.createTokenCookies(getHttpResponse(), requestToken,
				YahooConstants.YAHOO_TOKEN_COOKIE, YahooConstants.YAHOO_TOKEN_SECRETCOOKIE);
		OAuthUrl oauthUrl = authUrl;
		oauthUrl.setOAuthUrl(requestToken.getAuthorizationUrl());
		return oauthUrl;
		*/
	}

	private void deleteYahooCookies() {
		OAuthRequestUtil.deleteTokenCookies(getHttpResponse(), YahooConstants.YAHOO_TOKEN_COOKIE,
				YahooConstants.YAHOO_TOKEN_SECRETCOOKIE);
	}

	

	/**
	 * @param pYahooService
	 *            the YahooService to set
	 */
	@Required
	public void setYahooOAuthService(YahooOAuthService pYahooService) {
		mYahooOAuthService = pYahooService;
	}

	@Override
	public YahooModel getYahooMails(YahooOAuthVerifier pVerifier) throws YahooOAuthException {
		YahooModel model = new YahooModel();
		Long memberId = OAuthRequestUtil.getMemberId(getHttpRequest());
		try {
			OAuthAccessToken accessToken = mYahooOAuthService.getAccessTokenFromDB(memberId);
			if (accessToken == null) {
				/* Get request token from cookie. */
				OAuthRequestToken requestToken = OAuthRequestUtil.getOAuthTokenFromCookie(
						getHttpRequest(), YahooConstants.YAHOO_TOKEN_COOKIE,
						YahooConstants.YAHOO_TOKEN_SECRETCOOKIE);
				if (requestToken == null) {
					model.setLoginView(true);
					return model;// Go to login page, as there is no access
					// token in
					// db and no cookie.
				} else {
					accessToken = mYahooOAuthService.getAccessTokenFromRequestToken(requestToken,
							pVerifier.getOAuthVerifier());

					/* Store access token for future use */
					mYahooOAuthService.persistAccessToken(accessToken, memberId);
					deleteYahooCookies();
				}
			}
			// finally you got the access token which is stored in db.
			logger.debug("Getting yahoo mails for member=" + memberId);
			List<Mail> mailList = mYahooOAuthService.getYahooMail(memberId);
			model.setMailList(mailList);
			return model;
		} catch (Exception e) {
			deleteYahooCookies();
			logger.error("Error in fetching tweets", e);
			e.printStackTrace();
			throw new YahooOAuthException();
		}
	}
}
